QNW_TS_ClientCore = QNW_TS_ClientCore or {}

local this = QNW_TS_ClientCore
this.taskMap = {}
this.taskCategoryMap = {}

--注册任务类型
function QNW_TS_ClientCore.registerTaskCategory(_taskCategory)
    this.taskCategoryMap[_taskCategory.Type] = _taskCategory
    if QNW_TS_Util.isClient() then
        _taskCategory.registerClient()
    end
end

--注销任务类型
function QNW_TS_ClientCore.unregisterTaskCategory(_taskCategory)
    QNW_TS_Util.tableRemove(this.taskCategoryMap, function(k, v)
        return v.Type == _taskCategory.Type
    end)
    if QNW_TS_Util.isClient() then
        _taskCategory.unregisterClient()
    end
end

function QNW_TS_ClientCore.receiveTask(_task)
    local task = _task:new()
    QNW_TS_ClientCore.addTask(task,true)
end

function QNW_TS_ClientCore.receiveReward(_uuid, _rewards)
    local tasks = QNW_TS_Util.tableGet(this.taskMap, function(k, v)
        return v.uuid == _uuid
    end)
    for k, v in pairs(tasks) do
        v:loadReward(_rewards)
    end
end

function QNW_TS_ClientCore.addTask(_task,_init)
    local player = getPlayer()
    _task:registerClient(player)
    this.taskMap[_task.uuid] = _task
    if _init then
        _task:initReward()
    end
end

function QNW_TS_ClientCore.abandonTask(_task)
    this.taskMap[_task.uuid] = nil
end

function QNW_TS_ClientCore.EveryOneMinuteCallback()
    for k, v in pairs(QNW_TS_Util.tableCopy(this.taskMap)) do
        local now = getGameTime():getCalender():getTimeInMillis()
        if v.time ~= -1 and now >= v.time then
            this.taskMap[v.uuid] = nil
            if QNW_TS_TaskWindow.instance then
                QNW_TS_TaskWindow.instance:refresh()
            end
        end
    end
end

function QNW_TS_ClientCore.OnKeyPressedCallback(_key)
    local player = getPlayer()
    if _key == 34 then
        if QNW_TS_TaskWindow.instance then
            QNW_TS_TaskWindow.instance:destroy()
        end
        local maxY = getCore():getScreenHeight()
        local maxX = getCore():getScreenWidth()
        local ui = QNW_TS_TaskWindow:new((maxX - 400) / 2, (maxY - 600) / 2, 400, 600, player)
        ui:initialise()
        ui:addToUIManager()
    end
end

function QNW_TS_ClientCore.OnFillWorldObjectContextMenuCallback(_playerNum, _context, _worldObjects)
    local player = getSpecificPlayer(_playerNum)

    local taskSystemMenu = _context:addOption(getText("IGUI_QNW_TaskSystem"))
    local taskSystemSubMenu = ISContextMenu:getNew(_context)
    _context:addSubMenu(taskSystemMenu, taskSystemSubMenu)
    --生成物品
    taskSystemSubMenu:addOption(getText("IGUI_QNW_TaskSystem_Window"), _worldObjects, function()
        if QNW_TS_TaskWindow.instance then
            QNW_TS_TaskWindow.instance:destroy()
        end
        local maxY = getCore():getScreenHeight()
        local maxX = getCore():getScreenWidth()
        local ui = QNW_TS_TaskWindow:new((maxX - 400) / 2, (maxY - 600) / 2, 400, 600, player)
        ui:initialise()
        ui:addToUIManager()
    end)
end

function QNW_TS_ClientCore.OnCreatePlayerCallback()
    local player = getPlayer()
    if player:getModData().taskSystem then
        for k, v in pairs(player:getModData().taskSystem) do
            local task = _G[v.Type]:new()
            if task:isSave() then
                task:load(v)
                QNW_TS_ClientCore.addTask(task)
            end
        end
    end
    QNW_TS_ClientCommand.online()
    Events.OnTick.Remove(this.OnCreatePlayerCallback)
end

local tickCount = 0
function QNW_TS_ClientCore.OnTickCallback()
    if tickCount < 60 then
        tickCount = tickCount + 1
        return
    end
    tickCount = 0
    local player = getPlayer()
    local modData = player:getModData()
    modData.taskSystem = {}
    for k, v in pairs(QNW_TS_ClientCore.taskMap) do
        if v:isSave() then
            modData.taskSystem[k] = v:save()
        end
    end
end

if QNW_TS_Util.isClient() then
    Events.EveryOneMinute.Add(this.EveryOneMinuteCallback)
    Events.OnKeyPressed.Add(this.OnKeyPressedCallback)
    Events.OnFillWorldObjectContextMenu.Add(this.OnFillWorldObjectContextMenuCallback)
    Events.OnTick.Add(this.OnCreatePlayerCallback)
    Events.OnTick.Add(this.OnTickCallback)
end